package com.free.ext.quartz;

import java.util.concurrent.ConcurrentHashMap;

import com.free.exception.SystemRuntimeException;
import com.free.ext.quartz.job.DisConcurrentQuartzJob;
import com.free.ext.quartz.job.QuartzJob;
import com.free.ext.quartz.model.ConcurrentTaskEnum;
import com.free.ext.quartz.model.TaskStatusEnum;
import com.free.ext.quartz.tasker.Tasker;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;



/**
 * <p>
 * 功能概述: 
 * </p>
 * <p>
 * 功能详述: 
 * </p>
 */
abstract class Container
{
    /*========================================================================*
     *                         Public Fields (公共属性)                                                                
     *========================================================================*/

    /*========================================================================*
     *                         Private Fields (私有属性)                                                                
     *========================================================================*/

    private static final ConcurrentHashMap<String, Tasker> taskers = new ConcurrentHashMap<>();
    private StdSchedulerFactory stdSchedulerFactory;


    /*========================================================================*
     *                         Construct Methods (构造方法) 
     *========================================================================*/

    Container()
    {
        stdSchedulerFactory = new StdSchedulerFactory();
        try
        {
            Scheduler schduler = stdSchedulerFactory.getScheduler();
            schduler.start();
        }
        catch (Throwable t)
        {
            throw new SystemRuntimeException("定时任务容器创建失败", t);
        }
    }


    /*========================================================================*
     *                         Public Methods (公有方法)                                                                   
     *========================================================================*/

    void addTask(Tasker tasker)
    {
        String key = getKey(tasker.getGroupNm(), tasker.getTaskNm());
        taskers.put(key, tasker);
    }


    Tasker getTask(String groupNm, String taskNm)
    {
        String key = getKey(groupNm, taskNm);
        if (StringUtils.isEmpty(key))
        {
            return null;
        }
        return taskers.get(key);
    }


    <T extends Tasker> boolean checkTask(T task)
    {
        if (StringUtils.isEmpty(task.getGroupNm()) || StringUtils.isEmpty(task.getTaskNm()))
        {
            return false;
        }
        return true;
    }


    TaskStatusEnum getStatus(String groupNm, String taskNm)
    {
        Tasker tsk = getTask(groupNm, taskNm);
        return tsk.getStatus();
    }


    Class<? extends Job> getJobType(ConcurrentTaskEnum conEnum)
    {
        return conEnum == ConcurrentTaskEnum.YES ? QuartzJob.class : DisConcurrentQuartzJob.class;
    }


    boolean isTaskExists(String groupNm, String taskNm)
    {
        String key = getKey(groupNm, taskNm);
        return taskers.containsKey(key);
    }


    boolean pauseTask(String groupNm, String taskNm)
    {
        return pauseTaskForce(groupNm, taskNm, false);
    }


    boolean pauseTaskForce(String groupNm, String taskNm, boolean isForce)
    {
        Tasker task = getTask(groupNm, taskNm);
        if (task != null)
        {
            if (task.getStatus() == TaskStatusEnum.RUNNING && !isForce)
            {
                throw new SystemRuntimeException("暂停任务发生异常", String.format("任务暂停 组: %s 名称 %s 正在运行，不能暂停", groupNm, taskNm));
            }
            else
            {
                if (task.getStatus() != TaskStatusEnum.PAUSE)
                    return true;
            }
        }
        return false;
    }


    boolean canResume(String groupNm, String taskNm)
    {
        Tasker task = getTask(groupNm, taskNm);
        if (task != null)
        {
            if (task.getStatus() == TaskStatusEnum.PAUSE)
            {
                return true;
            }
        }
        return false;
    }


    boolean canRunNow(String groupNm, String taskNm)
    {
        Tasker task = getTask(groupNm, taskNm);
        if (task != null)
        {
            if (task.getStatus() != TaskStatusEnum.PAUSE)
            {
                return true;
            }
        }
        return false;
    }


    Scheduler scheduler() throws SchedulerException
    {
        if (this.stdSchedulerFactory != null)
        {
            return this.stdSchedulerFactory.getScheduler();
        }
        return null;
    }


    void updateTaskStatus(String groupNm, String taskNm, TaskStatusEnum status)
    {
        Tasker task = getTask(groupNm, taskNm);
        if (task != null)
        {
            task.setStatus(status);
        }
    }


    /*========================================================================*
     *                         Private Methods (私有方法)                                                                   
     *========================================================================*/

    private String getKey(String groupNm, String taskNm)
    {
        StringBuffer buffer = new StringBuffer();
        if (StringUtils.isNotEmpty(groupNm))
        {
            buffer.append(groupNm.trim());
        }
        if (StringUtils.isNotEmpty(taskNm))
        {
            if (buffer.length() > 0)
            {
                buffer.append(":");
            }
            buffer.append(taskNm.trim());
        }
        return buffer.length() > 0 ? buffer.toString() : StringUtils.EMPTY;
    }
}
